import numpy as np
import cv2 as cv


def Open_Frame_IRV(inpath, frame, width, hight):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    # frame  = 10   #irv：32*1024 视频的头，(640*480*2+1024) 一帧的长度
    f.seek(32 * 1024 + (frame - 1) * (hight * width * 2 + 1024), 0)  # 第一个代表需要移动偏移的字节数,0 代表从文件开头开始算起
    ccc = f.read(hight * width * 2)  # python在读取文件的时候是根据光标位置来读取的。读一行以后光标位置到了下一行。再来个read又到了下一行。
    img = np.frombuffer(ccc,
                        dtype='uint16')  # read的数值以bytes的类型保存，通过np.frombuffer方法还原成类型为uint16的ndarray，这种方式还原出来的ndarray是只读的。
    img = img.reshape((hight, width))
    # img=img[:-2,:-2] #去边缘黑边
    # img = np.squeeze(img)
    f.close()
    return img


# 读取视频总帧数
def Read_TotalFrame_IRV(inpath, w, h):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    f.seek(0, 2)
    size = f.tell()
    Total_num = int((size - 32 * 1024) / (w * h * 2 + 1024)) - 1
    return Total_num


# 求单帧视频中的最大最小AD值
def FindMaxMin(inpath, frame, width, hight):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    # frame  = 10   #irv：32*1024 视频的头，(640*480*2+1024) 一帧的长度
    f.seek(32 * 1024 + (frame - 1) * (hight * width * 2 + 1024), 0)  # 第一个代表需要移动偏移的字节数,0 代表从文件开头开始算起
    ccc = f.read(hight * width * 2)  # python在读取文件的时候是根据光标位置来读取的。读一行以后光标位置到了下一行。再来个read又到了下一行。
    img = np.frombuffer(ccc,
                        dtype='uint16')  # read的数值以bytes的类型保存，通过np.frombuffer方法还原成类型为uint16的ndarray，这种方式还原出来的ndarray是只读的。
    Max = max(img)
    Min = min(img)
    f.close()
    return Max, Min


# 线性拉伸
def imadjust(in_img, low, high):
    out_img = in_img * ((low <= in_img) & (in_img <= high)) + high * (in_img > high) + low * (in_img < low)
    out_img = (out_img - low) / (high - low) * 255
    out_img = np.uint8(out_img)
    return out_img


if __name__ == '__main__':  # 独立运行时测试用
    # test
    w = 640
    h = 480
    inpath = r'E:\红外实验视频\2023.11.28\depth\0.14hz_7s\7.IRV'  # IRV格式的原红外视频
    img_save_path = r'E:\studylife\detectflaws\code\python\ADimages\ADimages4_17_3mm'  # AD值方式显示的视频每帧图片存放位置

    # Total_num = Read_TotalFrame_IRV(inpath, w, h)  # 求视频的总帧数
    Total_num = 2400  # 可以自己设定需要分析处理的帧数
    # 求总视频中的最大和最小AD值
    Max_list = []
    Min_list = []
    for frame in range(1, Total_num + 1):
        Max_img, Min_img = FindMaxMin(inpath, frame, w, h)  # 求每帧图片的最大最小AD值
        Max_list.append(Max_img)
        Min_list.append(Min_img)
        print(frame, '帧图像获取AD值中')
    # 得到总视频中的最大和最小AD值
    Max_AD = max(Max_list)
    Min_AD = min(Min_list)
    print(Max_AD, "视频中最大AD值")
    print(Min_AD, "视频中最小AD值")

    # 将IRV类型视频保存为一帧一帧的图片
    for frame in range(1, Total_num + 1):
        img = Open_Frame_IRV(inpath, frame, width=w, hight=h)
        # 将img中的AD值进行线性拉伸归一化到0-255区间
        img2 = imadjust(img, Min_AD, Max_AD)
        print(img2)
        # 将一帧一帧图片保存到文件中
        img_path = f'{img_save_path}\\{frame}.jpg'
        print('正在保存第', frame, '张图片')
        # 写入图片
        cv.imwrite(img_path, img2)

